#pragma once
#include <iostream>
#include <sys/epoll.h>
#include <sys/epoll.h>
#include "log.hpp"
#include "common.hpp"
// 此文件功能：管理epoll: 创建epoll, epoll事件注册，epoll事件监测
const static int gsize = 128;
class epoller
{
private:
    bool event_mothod_core(int fd, uint32_t events, int type)
    {
        struct epoll_event ev;
        ev.events = events;
        ev.data.fd = fd;
        int n = ::epoll_ctl(_epfd, type, fd, &ev);
        if (n < 0)
        {
            LOG(ERROR, "epoll_ctl error!\n");
            return false;
        }
        LOG(INFO, "epoll_ctl add %d success!\n", fd); // TODO
        return true;
    }
public:
    // 创建epoll
    epoller()
    {
        _epfd = ::epoll_create(gsize);
        if (_epfd < 0)
        {
            LOG(FATAL, "epoll error!\n");
            exit(EPOLL_CREATE_ERROR);
        }
        LOG(DEBUG, "epoll create success, _epfd: %d\n", _epfd);
    }
    // 1. 添加文件描述符 2. 修改文件描述符 3. 删除文件描述符
    bool add_event(int fd, uint32_t events)
    {
        return event_mothod_core(fd, events, EPOLL_CTL_ADD);
    }

    // 等待在epfd指定的epoll实例上发生的事件
    int wait(struct epoll_event revs[], int num, int timeout)
    {
        int n = ::epoll_wait(_epfd, revs, num, timeout);
        return n;
    }
    bool mode_event(int sockfd, uint32_t events)
    {
        return event_mothod_core(sockfd, events, EPOLL_CTL_MOD);
    }

    bool del_event(int fd)
    {
        return ::epoll_ctl(_epfd,EPOLL_CTL_DEL,fd,nullptr);
    }
    ~epoller()
    {
        if (_epfd >= 0)
            ::close(_epfd);
    }

private:
    int _epfd;
};